/* ******************************************************************
 * This file is part of the escal project and distributed under the
 * terms of the GNU General Public License Version 3
 * Copyright (C) 2008 Epocher (xijiaosdq@gmail.com)
 * See COPYING file for licensing information.
 *******************************************************************/

#include "escal.h"
#include "initializer.h"
#include "log_manager.h"
#include "client_watcher.h"
#include "escal_settings.h"
#include <stdlib.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <QApplication>
#include <QDir>
#include <QTcpSocket>
#include <QTcpServer>
#include <QTextStream>
#include <QByteArray>
#include <iostream>

using namespace Escal;
using namespace std;

Initializer::Initializer(QObject *parent)
	:QObject(parent)
{	
	eInit=this;
	logManager=NULL;
	settings=NULL;
	dataDir=NULL;
	homeDir=NULL;
};

Initializer::~Initializer(){
	unInit();
	delete logManager;
	delete settings;
	delete dataDir;
	delete homeDir;
}

bool Initializer::initDaemon(int argc, char *argv[]){
	QString urlStr;
	bool gotUrl=false;
	if(argc >= 2){
		int i;
		for(i=1;i<argc;i++){
			if(argv[i][0] != '-'){
				urlStr = QString::fromUtf8(argv[i]);
				gotUrl = true;
				break;
			}
		}
		for(;i<argc;i++){
			argv[i] = argv[i+1];
		}
		if(gotUrl){
			argc--;
		}
	}
	server = new QTcpServer(this);
	if(!server->listen(QHostAddress("127.0.0.1"), quint16(ServerPort))){
		qDebug() << "connection status:" << server->errorString();
		cout << "eGear is running. " << endl;
		if(!gotUrl){
			exit(0);
		}
		cout << "sending new url..." << endl;
		QTcpSocket client(this);
		client.connectToHost(QHostAddress("127.0.0.1"),
				quint16(ServerPort));
		QByteArray array;
		QTextStream stream(&array);
		stream << CMT_NEW_URL << " ";
		stream << urlStr << endl;
		qDebug() << array;
		client.write(array);
		client.waitForReadyRead();
		QByteArray array2 = client.readLine();
		QTextStream stream2(&array2);
		qDebug() << "got msg:" << array2;
		int type;
		QString result;
		stream2 >> type >> result;
		qDebug() << type << result;
		if(type==SMT_OK){
			qDebug() << "succeeded";
		}
		else{
			qDebug() << "failed";
		}
		client.disconnectFromHost();
		exit(0);
	}
	connect(server, SIGNAL(newConnection()),
			this, SLOT(getNewConnection()));
	if(gotUrl) getUrlSlot(urlStr);
	return true;
}

bool Initializer::initFolders(int argc, char *argv[]){
#ifdef Q_WS_X11
	escalHome = QString(getenv("HOME"));
	escalHome = escalHome + QString("/.egear");
#else
	escalHome = argv[0];
	int last = escalHome.lastIndexOf('/');
	if(last >=0) escalHome.resize(last);
	else escalHome.resize(0);
#endif /* Q_WS_X11 */
	dataHome = escalHome + QString("/cache");
	homeDir = new QDir(escalHome);
	dataDir = new QDir(dataHome);
	if(!homeDir->exists()){
		if(!homeDir->mkdir(escalHome)){
			exit(1);
		}
	}
	if(!dataDir->exists()){
		if(!dataDir->mkdir(dataHome)){
			exit(1);
		}
	}
	return false;
}

bool Initializer::initSettings(){
#ifndef Q_WS_X11
	settings = new EscalSettings("egear");
#else
	settings = new EscalSettings(escalHome + QString("/egear.conf"),
		QSettings::IniFormat);
#endif /* Q_WS_X11 */
	return false;
};

bool Initializer::initRuntime(){
	qApp->setQuitOnLastWindowClosed(false);
	logManager = new LogManager;
	curl_global_init(CURL_GLOBAL_DEFAULT);
	return false;
};

void Initializer::getUrlSlot(const QString &urlStr){
	qDebug() << "getUrl:" << urlStr;
	emit passUrl(urlStr);
};

void Initializer::unInit(){
	qDebug() << "Initializer::unInit()";
	curl_global_cleanup();
	settings->sync();	
};

void Initializer::getNewConnection(){
	qDebug() << "Initializer::getNewConnection()";
	QTcpSocket *socket = server->nextPendingConnection();
	ClientWatcher *client = new ClientWatcher(socket);
	connect(client, SIGNAL(quited(ClientWatcher *)),
			this, SLOT(clientQuited(ClientWatcher *)));
	connect(client, SIGNAL(getUrl(QString)),
			this, SLOT(getUrlSlot(QString)));
	client->start();
	clientList << client;
};

void Initializer::clientQuited(ClientWatcher *client){
	client->deleteLater();
	clientList.removeAll(client);
};
